package cn.wolfcode.luowowo.redis.redisService.impl;

import cn.wolfcode.luowowo.domain.Travel;
import cn.wolfcode.luowowo.redis.key.RedisKeys;
import cn.wolfcode.luowowo.redis.redisService.ITravelStatisVoService;
import cn.wolfcode.luowowo.service.ITravelService;
import cn.wolfcode.luowowo.util.DBHelper;
import cn.wolfcode.luowowo.util.DateUtil;
import cn.wolfcode.luowowo.vo.TravelStatisVO;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;


@Service
public class TravelStatisVoServiceImpl implements ITravelStatisVoService {

    @Autowired
    private StringRedisTemplate template;
    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private ITravelService travelService;

    @Override
    public void replynumIncrease(String travelId, int i) {
        //1.获取缓存中的vo对象
        //在获取方法中已判断了存在不存在的两种情况处理操作
        TravelStatisVO vo = this.getTravelStatisVo(travelId);

        //2.把vo对象中的viewnum 加1
        vo.setReplynum(vo.getReplynum() + 1);

        //3.更新vo对象到缓存中
        this.setTravelStatisVo(vo);
    }

    @Override
    public void viewnumIncrease(String travelId, int i) {
        //1.获取缓存中的vo对象
        //在获取方法中已判断了存在不存在的两种情况处理操作
        TravelStatisVO vo = this.getTravelStatisVo(travelId);

        //2.把vo对象中的viewnum 加1
        vo.setViewnum(vo.getViewnum() + 1);

        //3.更新vo对象到缓存中
        this.setTravelStatisVo(vo);
    }

    //获取vo对象
    @Override
    public TravelStatisVO getTravelStatisVo(String travelId) {
        //1.根据游记id 拼接缓存中游记统计数据的key
        String key = RedisKeys.TRAVEL_STATIS_VO.join(travelId);

        //2.判断key是否存在 获取或初始化vo
        TravelStatisVO vo = null;
        if (template.hasKey(key)) {
            //若存在,直接根据key获取并转换成对象
            String value = template.opsForValue().get(key);
            vo = JSON.parseObject(value, TravelStatisVO.class);
        } else {
            //若key不纯在 初始化一个vo对象 并存入缓存中
            //先从数据库中查询出当前游记的统计数据对象 并拷贝数据到vo对象
            Travel travel = travelService.get(travelId);
            vo = new TravelStatisVO();
            BeanUtils.copyProperties(travel, vo);
            vo.setTravelId(travelId);//字段不同所以单独赋值
            //vo对象初始化完 存入缓存中
            template.opsForValue().set(key, JSON.toJSONString(vo));
        }
        return vo;
    }

    //存入vo对象
    @Override
    public void setTravelStatisVo(TravelStatisVO vo) {
        String key = RedisKeys.TRAVEL_STATIS_VO.join(vo.getTravelId());
        template.opsForValue().set(key, JSON.toJSONString(vo));
    }

    //收藏或取消收藏操作
/*    @Override
    public boolean favor(String travelId, String userInfoId) {
        //1.根据用户id获取在缓存中的的已收藏游记id集合
        List<String> list = travelFavorRedisService.getFavorRedis(userInfoId);

        //2.判断当前游记id 在不在 已收藏的游记id集合中
        //先获取缓存中的vo对象
        TravelStatisVO vo = this.getTravelStatisVo(travelId);
        boolean ret = true;
        if (list.contains(travelId)) {
            //3.如果在 即当前操作是取消收藏 并使收藏数 -1
            //在已收藏的游记id集合中 移除当前游记id
            list.remove(travelId);
            //使收藏数 -1
            vo.setFavornum(vo.getFavornum() - 1);
            ret = false;//取消收藏返回结果是false
        } else {
            //4.如果不在 即当前操作是收藏 并使收藏数 +1
            //把当前游记id 增加到已收藏的游记id集合
            list.add(travelId);
            //使收藏数 +1
            vo.setFavornum(vo.getFavornum() + 1);
            ret = true;//收藏返回结果是true
        }
        //3.更新list vo到缓存中
        travelFavorRedisService.setFavorRedis(userInfoId, list);
        this.setTravelStatisVo(vo);
        return ret;
    }*/

   /* @Override
    public boolean thumbup(String travelId, String userInfoId) {
        //1.根据用户id和游记id拼接key
        String key = RedisKeys.TRAVEL_THUMBUP.join(userInfoId, travelId);
        //2.如果不存在,创建缓存标记 设置有效时间 (当天的最后一秒减去当前秒)
        if (!template.hasKey(key)) {
            Date date = new Date();//当前时间
            Date endDate = DateUtil.getEndDate(date);//当天的最后一秒对象
            //有效时间等于 = 当天的最后一秒 - 当前秒
            long time = DateUtil.getDateBetween(date, endDate);
            template.opsForValue().set(key, "1", time, TimeUnit.SECONDS);
            //使点赞数加一  更新Vo对象
            TravelStatisVO vo = this.getTravelStatisVo(travelId);
            vo.setThumbsupnum(vo.getThumbsupnum() + 1);
            this.setTravelStatisVo(vo);
            return true;
        } else {
            return false;
        }
    }*/

    @Override
    public boolean isVoExsits(String travelId) {
        TravelStatisVO vo = this.getTravelStatisVo(travelId);
        if (vo == null) {
            return false;
        } else {
            return true;
        }
    }

    @Override
    public List<TravelStatisVO> listTravelVoByPattern(String pattern) {

        //1.使用keys travel_statis_vo:* 方法获取所有key
        Set<String> keys = template.keys(pattern);

        //2.遍历所有key获取所有vo对象
        ArrayList<TravelStatisVO> vos = new ArrayList<>();
        if (keys.size() > 0 && keys != null) {
            for (String key : keys) {
                String voStr = template.opsForValue().get(key);
                TravelStatisVO travelStatisVO = JSON.parseObject(voStr, TravelStatisVO.class);
                vos.add(travelStatisVO);
            }
        }
        return vos;
    }

    //把游记vo中的数据 存入mongodb中对应的游记中
    @Override
    public void updateTravelVo(TravelStatisVO vo) {

        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(vo.getTravelId()));
        //从vo拷贝数据到travel
        Travel travel = new Travel();
        BeanUtils.copyProperties(vo, travel);
        DBHelper.update(mongoTemplate, query, travel, "viewnum",
                "replynum", "favornum", "sharenum", "thumbsupnum");
    }
}
